﻿using DSInternals.Common.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Security.Principal;

namespace DSInternals.Common.Test
{
    [TestClass]
    public class CredentialRoamingTester
    {
        private static readonly SecurityIdentifier TestSID = new SecurityIdentifier("S-1-5-21-4534338-1127018997-2609994386-500");
        private const string TestUser = "Administrator";


        [TestMethod]
        public void RoamedCredential_ParseCAPIPrivateKey()
        {
            byte[] blob = @"25315C37303135373731343139383562363932333939386463636130333563303037615F66386237626265662D643232372D346163372D626164642D336132333861376637343165000000000000
0000000000000000000000000000000000008DF920427929D20100000000D41B2B4879E46B1F93F1BDFE8D86F75EAAD3420E2108000002000000000000002500000000000000000000001C010000
FC0500001400000000000000A800000034373235373662392D313464362D343463332D626661662D6263636430373464343639350000000000000000000000000000000000000000005253413108
01000000080000FF0000000100010015F393BA9EF4CDD11980528B9AEC004F0676DE4E6D3539D779305382B32A040962C1D0FF8207E1A4A07AA52BAA1D89FC01E215061B85A0F1EB4C8E894F1E98
DD3E3DF3B9379762CB301E37E2C56A71EE0E542C9255389C7213DC4781C230E9E4F55FDA3AA05BFC88C67088C8DD7366AA72BFE602B657061DA204AE9F54BD1BE9391FE8EF0A81F1E5492F706D75
267C7512301776225AA40230D88ECA9DCE49249482A9BBFE9AD26516875373458D0BFDA5899FE8EFCFAFA0EA5B286E6F6D1B3F3E27BAC7B495D9416C3D4918CB73AFFDD7B0CF91F45B5CB75FBF0E
5EAC7E81A068A132CD7318FE07CAAF7AA8E8AB1075EF9705BD044A001CC0707937AAB66598000000000000000001000000D08C9DDF0115D1118C7A00C04FC297EB010000006006074759C2904D8B
C9187605323450000000002C000000430072007900700074006F004100500049002000500072006900760061007400650020004B0065007900000003660000C000000010000000D2B733BECC0353
CBBBADA2281992176F0000000004800000A0000000100000002150632E92804157DAEF6651076D9C1848050000A706A82DDBB03DCC08F486B16BF839EE3A943327925CC6BF9551E5A69DFEFC24D1
9EC55A2D3BD702EACF6207E2F23F2AF981B4CDB4E3C645E98B8979CA967A461351865A40B98077F02414578B4D34F88C5F86D91B0845B75644AC52F9307FDDD1F1A088451EC33695FBE379FF0FBC
0424CFD7E7FD14C7048B418DB09934E87421D6636B4B5314FDA747B39176A9FB1FFE838C52FC5E5FC0E6CD8CFB5D8B760BF2C1C63525E43878B6E341060D3AF235DFE343F1056D255BC1F01801CA
22A7B6BC7B98F0E0EF8BFE529CF96CFC1A47E560FA4AAC32C40EC5BBDF50798B5B2F64768814DFEAC40E10DECA72015D50830DE74FFD4A9DA575D3FAEB3542653DF243ED838B462A94507C0273B9
BE1B4D603DD6B23A956A81F316A68B474BA96113C0E3C19253A441AA24B127360371B0DF8A28DC33692D02A9B10FAC6581386C8382D8C40F8742EADCF9C7ECEAA5F6B8104EEE0A47A169CF68566E
53CBD961624ABB35263A6AA82BC77816012BC227F76B6147A1C47AEF830D519E288324195F5AEE3453496DF944D700AAF5511943A3A1EB6E89BB495D8791BDFD75613FA954EEB346BF11031A9F93
129C4140156CC80BA247B6370918E0B1BC7BB74C160F4F85D60CD7FC221CCA40A81EAF5242AD1EA9CA23A09848DEE6D21B645022250EF52B27155AF778C95FF26609EBE62F94F9F87550CC725891
E90AD68015BE60BCC8AD66D924D72C6CBEDA2ED58516CCD7BC70BB6AB606C970139082BC20537203E042CD4CED6E12E4B66BF2C80B92B05773E6368C82FD3311CA04B0847F37ECAA2A13BE041F05
40D76D78C7DC7C4EBE138CB16A1DAB7291A3AB2259A1BCBA674AEBD344E09A739DDF23A152DC871FF2B982416DCDD024D07C7B7D7989BFF6BA2854D7FAEC3DE4F16086AC40C6051F7270EA9ABB33
DA177923F1ABE996DE02BFBDCCA1EF4C18687CFC609242450CD68C4C1B01ADB2A17B3464C22AF6A06C6845D0C7E41C0A95A559FE1D52260E708CBBB1153DC052AB428734B9001200F8F2994453AC
66240D46237818906C04B05256DAA3522C8AC8B1FD2E249646558F99BC5B52582EBECD09251D9623F9BBE8C6822FE6DF419870CF2B96C6F145894B8D89719C0F51764DFC8CB79BEA0064B94E8442
0FD15558A6B1D59E66900123923C05649A0069AE7935B69C6F317CD970EFCC6F5B66D02BD61318DAB7AE765CA47AFCF0AC21F61B7D03F2897B31559D901134765B76967D6E48CB9F111DBDE8E64D
8BCB16CA165959902A09F92C7B98A71CE6BB78A3D5DB35A633A860510B80190591460CDA4AF5943B68A8EEB6DA5D2BDB860B35B092C64ACE8B6D185A9829540A2D915FD4CE6B76B766FEA283E3B6
3843E047CEC90C41F552425AACD65D8FBABB4F586DD42156A9FDA69737E8E34FF2C11AF8D4463A1F101EDCDEFE410EFF14A9FAADEEDCA3A96E696279838D3ECAD0F049280ECEE181A5B0B3F97039
D960C85C25BC6433FAE2E0E04ADC96820350FD88B92922F40F3F2855FE2573746A9CE2D3E9B9F7BB75D23762CAABF88DC787744947D60FE1254F08B6B9F183DC721C809687A3BF609AA0F75BA43C
7CA5C9C4B779768EB4338B178F7D2D86BBF546FDB4B907B532BA087097A2C4AB99799B86942CE63F058EE2B7D8C8869AC0418508CED08690501AD81CD28304932426D4B060C8748BDA711C1DFC21
182FCA6D7A884E97F2C56626D28D62E0886C377BE4AEE94985C051B2704D727375D6C2585982E81762DE73A64800EE600E62831B938C20CDFB9FD5759DB22C5EC0714FF8E0EE6F0818B8B6ACC16B
3A9E8088F1AB36F4D50C39613D90089531E2332E1F980BFF77B8E478637B6F2FD1C37B8851B52A9C1B8F5E0DC02474D13703BC6C7E0C3170C0C2D339F265799F15117C22CEB8EA14000000FEC87A
14F4862F438251DDDB8A389ADE8041AB7001000000D08C9DDF0115D1118C7A00C04FC297EB010000006006074759C2904D8BC918760532345000000000180000004500780070006F007200740020
0046006C0061006700000003660000C000000010000000EEB69DA1D9AD80A5AB22EA2F53EC51590000000004800000A000000010000000ACA16AD7D5BFE8436BEA3491E31F8A7E0800000051FA5F
D696BC1BBA1400000029B473EA61602F51CDCCB15C5982D3F6F83D09EB".Replace(Environment.NewLine, String.Empty).HexToBinary();

            var roamedObject = new RoamedCredential(blob, TestUser, TestSID);
            Assert.AreEqual(@"Administrator\Crypto\RSA\S-1-5-21-4534338-1127018997-2609994386-500\701577141985b6923998dcca035c007a_f8b7bbef-d227-4ac7-badd-3a238a7f741e", roamedObject.FilePath);
            Assert.AreEqual(RoamedCredentialType.RSAPrivateKey, roamedObject.Type);
        }

        [TestMethod]
        public void RoamedCredential_ParseCNGPrivateKey()
        {
            byte[] blob = @"25395C4236414631454639443330324137333332323038303931434338433145464638333646363036323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003311230B7245D50100000000E7BC05536BF32A36076051BFACD2D1ADCD8DE62E9D0800004D4942313800000000000000050600000000000000000000D401000000000000000000000000000000000000000000000000000000000000000000000000000000000000740065002D005300570053006D0061007200740063006100720064004C006F0067006F006E002D00330034003600320064006300620066002D0031003200350032002D0034003600310039002D0061006400370066002D00390032003900360065003100660032006200340032003600010000000000000070000000010003005B0100004E010000C002000000000000000000000000000000000000740065002D005300570053006D0061007200740063006100720064004C006F0067006F006E002D00330034003600320064006300620066002D0031003200350032002D0034003600310039002D0061006400370066002D003900320039003600650031006600320062003400320036002C000000000000000000000010000000080000004D006F006400690066006900650064003311230B7245D5012F0100000A00000000000000000000001B010000525341310008000003000000000100000000000000000000010001D5F8A98B58B30326A7706FAC394B1A59745B46EECF28257E3FD3518137A78C42479F8ED38BC3894E80B383873851C53F41F4BF8DF047D564730847A22E8834143D363E59291760A81912AE5132E7492F24A2CDB540552CDA6F25AFFB737C123A43E59EE9C5DA190176B65E76B5B236935DB8EE345D67B173178104BE9E8EEE4BF5B07EB1047455C2FDC17702021525A22B684F5987FC50CD0B5612761380973EE47A27AD8949410252C455C52BE60790DF5FE0B96969BA8D821D1BCCD7171971989CF450B53916506702988F877CD5835FA9E48147EA96E664B5DD29B4DB5B664F202C1499142719BD98A55A6AFA2F063F6634CDDC54A418EE2118931EE8656D01000000D08C9DDF0115D1118C7A00C04FC297EB01000000107E3E56510355488F9A5C6BA86A2C04000000002E000000500072006900760061007400650020004B00650079002000500072006F007000650072007400690065007300000003660000C0000000100000006869B42E88AA5AECD03823E5C76B7DE60000000004800000A000000010000000DA703547CDC8F68643081C3D24DF5A71980000005868F9E8FD5F3A962937C42E0ADA0869C182E0090D313965D7C0A1D170D17B904001D697A60F826B60C4165B7FFA579DD0D1F0BE53D39C181A82ED052DA0C6D8C49A0E2C00022E93A85E15EA5A149C6D1873987274D01A52D515752EF5390F9D48A58F3F8302BEBB7C6A9A08FD223E6CA6CC0FCD3EDEAA9F9EA6887AF943EBECCC61AF2472E31D7A6EB5E913BCF27F24254FA451F94BCFB4140000005EF7DC638D1B7A13E252182DAD4F1933218B619101000000D08C9DDF0115D1118C7A00C04FC297EB01000000107E3E56510355488F9A5C6BA86A2C040000000018000000500072006900760061007400650020004B0065007900000003660000C000000010000000F115DF8D275D28BE5483592FBFA38CD60000000004800000A000000010000000AE22691BEE4868D06ECFA8BB2A22F17620020000F04784A72087CE7D40A33BBE7AD40401DCADAF35900C9FA89562718475B1E92B40C692C1A846B1CAADB115B0D0ACDBC1DD1D679A1119706088CD5F27CB0BE5F127C0E10696D8A946821BC9B0272495DFF0A0F2BFAB81118FE04CFED158EFC9CF33B756D706F9CC8373876E7B713F664B67C109FE32D2F605BEE6DF6F601CA87E79A14E6D883E0B1F215A9EAF4996D1EECF87CA38A15C44CB23B313B6C2D1F3183F06E0A1CDE23C827ED560C6A59417EE02043823D1F8DD9C7DA051F1878B1F0DD55E36EA80087E0090E15B7DE79FFBD51A0EEE1321343566BA6248CE80F6F8B62203D57A0666187E5501ABD4B1CDB0F85A61E2935F77AE959816503E51D3535558837CF7AD79615D5E6838261851DA8ACB08E4823F1767B480FD35CABA8FF3AEA72ABDB8FBA96B051DAB242EB0D1AFC1506C822C45001F9D09B113EA90F05573F1DB9A1E6F88388D4B4C28408EE2C6F43A12AC1AD037F465F94D9D37AC4D0A97D6B47A15BC044EE7B0643A16C5C53F0C43BF3F4DDE2E7C227687485B5C7849B6A02AD732CB9520220ADD8AB7B28694375EC4D1E8EAE8AA4395D405240FD7F5DE2C45D727E2937F1D959704C7B8C46EEEB1126DB9E146BC811E064F047FD784194EE357BB32F5EA7EDDC1EDB788A257AAAF956B7FC3BAA539EECD40918F9C93F4A866D625BE165C2758CFB6A5B919957D4A7297A502C62CA4881E6F3F4A9FC6CED6330A838486F5BB3D66C4ECAE90019AB5E3930633E4EE632359F057E9136ABD14000000A0957D3AAE539B639E7A08F99138FC427FBD18D6107E3E56510355488F9A5C6BA86A2C04020000000000000000000000350036003300650037006500310030002D0030003300350031002D0034003800350035002D0038006600390061002D00350063003600620061003800360061003200630030003400000000000000000005000000B0000000000000009000000000000000140000000000000000000000000000000200000072B55BAA9AFF23AEA1A977B2B5CC3EFE401F00000E80000010660000C53C6350C3B2385F2B3E03E6EC717C141103E23E8DF4316A4A39A29F335FCE1BC2576A03EA0AB8A524AE206A8B40216AA8450DED9EA7B93CCA7B8FE88A869DFBD7C1D1B4EDCA75A2F5FA4E53B8DF7D66D772B4C3C25B9E89417B466E13E7BA7A6A47591CA018C0B92DF6F2B7CBCC20389B800BF5D5D7C8667581D696003730BB516D56ECA5CFB732BCC96B89C5812B05020000002591ED959C185502297B198067EBAB02401F00000E800000106600003EA13DB998285EEEB7C692324223215AF8EC670B489CCE174D186DCE86639C3717390BF9E851CABA0E01B0E30D14CF3EC0FD65B43415FEBF89098B4EEDFA026F86EC4F226363A272FDF31B20FE1DFA8383739F84118CDE23BE02AAEB45E02011BB5CC347093A4316803C96BD3244C1A70300000015EE4EA44BF5FD4DA50B452BBD415B0E".HexToBinary();

            var roamedObject = new RoamedCredential(blob, TestUser, TestSID);
            Assert.AreEqual(RoamedCredentialType.CNGPrivateKey, roamedObject.Type);
            Assert.AreEqual(1541, roamedObject.Data.Length);
            //TODO: Check that the file path name is "Administrator\Crypto\Keys\02859e067a0b05861e1b51a3ef3e70d0_1779c438-1e9e-4a06-9bc5-90755acd7d96"
        }

        [TestMethod]
        public void RoamedCredential_ParseCertificate()
        {
            byte[] blob = @"25375C334238334246413730333746364137394233463344313744323239453142433039374633354235310000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000341057FDD79BD20100000000E76B79D2C7A156F99355453C
46F2B18AF34F36929E0800000300000001000000140000003B83BFA7037F6A79B3F3D17D229E1BC097F35B510400000001000000100000005AFDB1B9
7F0CA8854A7CEB769D29E60C0F0000000100000020000000E8DA73161869CEE3CD1831930B518C9E1AC821965362C81A7073923A1E428F8D14000000
0100000014000000C6B90B1EB003176318069C64188E7BFCF02E249C190000000100000010000000BAFE94625F44C69DB1DF36D9D1809A755C000000
010000000400000080010000180000000100000010000000092CE6B50EA57C67CA5F0CD5A4D3D12B0200000001000000DC0000001C0000008C000000
0000000000000000000000000000000000000000740065002D005400650073007400540065006D0070006C006100740065002D006400640061003600
61003200390062002D0033006500330038002D0034003500320038002D0038003700380035002D003700630039003500640033003000630036003300
3100610000000000000000004D006900630072006F0073006F0066007400200053006F0066007400770061007200650020004B006500790020005300
74006F0072006100670065002000500072006F007600690064006500720000005700000001000000AA00000000000000000000000200000000000000
020000006C006400610070003A0000007B00340044003700450045003400440046002D0031003100390044002D0034004500370030002D0039004500
440037002D003400450030003300340033004200380034003100390038007D0000004C004F004E002D004400430031002E0041006400610074007500
6D002E0063006F006D005C00410064006100740075006D00430041000000380000004700000001000000260000004C004F004E002D00440043003100
2E00410064006100740075006D002E0063006F006D0000002000000001000000F2050000308205EE308204D6A0030201020213310000000801331C27
9CE80A49000000000008300D06092A864886F70D01010B0500304031133011060A0992268993F22C6401191603636F6D31163014060A0992268993F2
2C640119160641646174756D3111300F0603550403130841646174756D4341301E170D3137303331333038343833315A170D31383033313330383438
33315A307631133011060A0992268993F22C6401191603636F6D31163014060A0992268993F22C640119160641646174756D310E300C060355040313
055573657273311630140603550403130D41646D696E6973747261746F72311F301D06092A864886F70D010901161061646D696E4061646174756D2E
636F6D3076301006072A8648CE3D020106052B810400220362000411EFB0F2F5CEDE627BB0D2AEB6B1348B691AAFA30C3B7A6C47B6B43FB675EB0FE1
2B9D3A96077A8B3AA1A0529E79698D4F305E8705A197080F4B8E8D95FDB47A227FD1E4270263558C830D6537F64FEEAF7C2466DC6ACC180D3EC30C78
DFF6FBA382035730820353303D06092B06010401823715070430302E06262B060104018237150881EAD24A82B9D44F8285812486BFCE3481A1B36F5C
838A921C87F6D66702016402010530290603551D250422302006082B0601050507030206082B06010505070304060A2B0601040182370A0304300E06
03551D0F0101FF040403020388303506092B060104018237150A04283026300A06082B06010505070302300A06082B06010505070304300C060A2B06
01040182370A030430819406092A864886F70D01090F048186308183300B060960864801650304012A300B060960864801650304012D300B06096086
48016503040116300B0609608648016503040119300B0609608648016503040102300B0609608648016503040105300A06082A864886F70D03073007
06052B0E030207300E06082A864886F70D030202020080300E06082A864886F70D030402020200301D0603551D0E04160414C6B90B1EB00317631806
9C64188E7BFCF02E249C301F0603551D230418301680146AF07A64567C7258EDF4CD002D3B7AB711896EE93081C50603551D1F0481BD3081BA3081B7
A081B4A081B18681AE6C6461703A2F2F2F434E3D41646174756D43412C434E3D4C4F4E2D4443312C434E3D4344502C434E3D5075626C69632532304B
657925323053657276696365732C434E3D53657276696365732C434E3D436F6E66696775726174696F6E2C44433D41646174756D2C44433D636F6D3F
63657274696669636174655265766F636174696F6E4C6973743F626173653F6F626A656374436C6173733D63524C446973747269627574696F6E506F
696E743081B906082B060105050701010481AC3081A93081A606082B060105050730028681996C6461703A2F2F2F434E3D41646174756D43412C434E
3D4149412C434E3D5075626C69632532304B657925323053657276696365732C434E3D53657276696365732C434E3D436F6E66696775726174696F6E
2C44433D41646174756D2C44433D636F6D3F634143657274696669636174653F626173653F6F626A656374436C6173733D6365727469666963617469
6F6E417574686F7269747930450603551D11043E303CA028060A2B060104018237140203A01A0C1861646D696E6973747261746F724041646174756D
2E636F6D811061646D696E4061646174756D2E636F6D300D06092A864886F70D01010B050003820101006327F8EF29C43A9C0479BC5D4149F3F0836A
62BD96C641C8333291C5020D057015B64139DF67702BF4738384B74A4FE8C7EED6C8CF5CEAB57A281C367C34A5CB60C87D487331F1051B231FCF1F2B
BAA60416FC595319FB786F77167679F01908519F2BE75A0EF062C90ACF56C117AA3B3416B7FBE60B8E0A25898047C0F6E8AB4BCCD2D8A8081DB8D124
5CB502A193269E1E588546058DD69789E3AF119A45A3D8294F8BEB74BB1BDF802F8637AA9984A7FB7460F4A695F2F98B567F766C259D82577FF6BE09
F1C522630C6A625070E8F81671A7A4BBB8D1FFBA4DA094B48C64050810306BB3FB538069FB87DCFBF00501B9D0A99DDF6C93CC0774660C97564E".Replace(Environment.NewLine, String.Empty).HexToBinary();

            var roamedObject = new RoamedCredential(blob, TestUser, TestSID);
            Assert.AreEqual(@"Administrator\SystemCertificates\My\Certificates\3B83BFA7037F6A79B3F3D17D229E1BC097F35B51", roamedObject.FilePath);
            Assert.AreEqual(RoamedCredentialType.CNGCertificate, roamedObject.Type);
        }

        [TestMethod]
        public void RoamedCredential_ParseDPAPIMasterKey()
        {
            byte[] blob = @"25305C37666331393530382D376238352D346137632D396535642D313566396530306537636535000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000EBB3A881D59BD20100000000CCCE248D66614EFB99F31BCC
2AC3B14F606C8EE6E4020000020000000000000000000000370066006300310039003500300038002D0037006200380035002D003400610037006300
2D0039006500350064002D00310035006600390065003000300065003700630065003500000000000000000000000000880000000000000068000000
0000000000000000000000007401000000000000020000009BA729B47F0A0EE96B22B8BBE865A8DE504600000980000003660000326997D5121CEE91
A88E32B910F3F202595FB17EAD63E005BBD5FD5B02106281D447A1AB654B7AE562F07C2881AD41DC452579E9B5A788F0FBA48B103BEC470F918D71D0
91DF3B9CCFB42AD640D7A958E99D652C665EFDB0F39F5E05EBA46AC5B2A698DB39E1F125020000003F45EDDED1C3169D672D85E40052E14550460000
0980000003660000E1F98780DE1BE48EB5306E448701B654CA81B0F5ACF19219509A5BCEE30AC64E00D786864EF3E783CB6FDC2B97407596DBDEF990
10D6A065DC5B15EBC90642135E0485ADB5C7E21B020000000001000058000000EC56E7EF7CF83A49902F2590302034451B5D88A85E011FEE9C07EBD5
7BDE0BD80F9FF79D8776C5AC8406E42B17E064F51A82480A6D179EEB30CBF4D39F1D446BA71F50A500C702FC3A5B0EF6CB126F0E00BEA30EFBE331E3
DCD2F6E392B6867C0836B85F64D95BC5F506D213070CD973417A049A775C5907E903CE595603AFDE734C7C52BC8262CC3D399C2F76B297DAA86EE7B1
0EBBBCACF0A57B6BEB9CBFE56C38C2688B7C3A0B29C06F55F7B77B7F86E0719B441572C36B67047C6F6900B6AB63DCB56E709FE7F263C040CF3384D1
7D64BADAB8261346F6C2B0267D03B04F6E6244DB6431AEF5803981F06B80771A90A94E932EBB9F3A9AEE63CA703343CB011130839AE8675070387B21
6C5775987EDD54E424B989705150124E0B59132E4617DC94D20C85769FA0E7D493DF5F58AD9B2465425E78C8E0E71DB2D8EBB359A451F1D3E386A96A
248345A9FA22CA076AFF971F55829D1426D3667084194C1318B34587E014C5DF".Replace(Environment.NewLine, String.Empty).HexToBinary();

            var roamedObject = new RoamedCredential(blob, TestUser, TestSID);
            Assert.AreEqual(@"Administrator\Protect\S-1-5-21-4534338-1127018997-2609994386-500\7fc19508-7b85-4a7c-9e5d-15f9e00e7ce5", roamedObject.FilePath);
            Assert.AreEqual(RoamedCredentialType.DPAPIMasterKey, roamedObject.Type);
        }
    }
}
